package com.wjk.kylin.modules.system.user.controller;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.wjk.kylin.core.common.aspect.Log;
import com.wjk.kylin.core.common.controller.BaseController;
import com.wjk.kylin.core.common.data.RequestData;
import com.wjk.kylin.core.common.data.ResponseData;
import static com.wjk.kylin.core.constant.CommonConstant.BusinessType.*;

import com.wjk.kylin.core.common.redis.RedisRepository;
import com.wjk.kylin.core.common.valid.insert;
import com.wjk.kylin.core.common.valid.update;
import com.wjk.kylin.core.constant.Constants;
import com.wjk.kylin.core.exception.BusinessException;
import com.wjk.kylin.core.exception.RequestException;
import com.wjk.kylin.core.utils.DateUtils;
import com.wjk.kylin.core.utils.PageUtils;
import com.wjk.kylin.core.utils.SecurityUtils;
import com.wjk.kylin.core.utils.excel.ExportExcel;
import com.wjk.kylin.core.utils.excel.ImportExcel;
import com.wjk.kylin.modules.system.user.entity.User;
import com.wjk.kylin.modules.system.user.service.IUserService;
import com.wjk.kylin.modules.system.user.vo.UserExportVO;
import com.wjk.kylin.modules.system.user.vo.UserImportVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3. StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author wangjkui
 * @since 2020-06-01
 */
@Slf4j
@Api("用户")
@Validated
@RestController
@RequestMapping("/sys/user")
public class UserController extends BaseController {
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisRepository redisRepository;


    @PreAuthorize("hasAuthority('system:user:list')")
    @ApiOperation("列表")
    @Log(title = "用户-列表",businessType = LIST,isSaveResponseData = false)
    @GetMapping("/list")
    public ResponseData list(User user) {
        IPage<User> page = userService.findPage(new RequestData<User>(),user);
        return ResponseData.success().data("page",new PageUtils(page));
    }

    @PreAuthorize("hasAuthority('system:user:query')")
    @ApiOperation("详情")
    @Log(title = "用户-详情",businessType = GET)
    @GetMapping("/{userId}")
    public ResponseData get(@PathVariable String userId) {
        User user = userService.getById(userId);
        return ResponseData.success().data("user",user);
    }

    @PreAuthorize("hasAuthority('system:user:add')")
    @ApiOperation("新增")
    @Log(title = "用户-新增",businessType = INSERT)
    @PostMapping
    public ResponseData save(@Validated(insert.class) @RequestBody User user) {
        boolean flag = userService.save(user);
        if(flag){
            return ResponseData.success();
        }else {
            return ResponseData.error("新增失败");
        }
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @ApiOperation("编辑")
    @Log(title = "用户-编辑",businessType = UPDATE)
    @PutMapping
    public ResponseData update(@Validated(update.class) @RequestBody User user) {
        boolean flag = userService.update(user);
        if(flag){
            return ResponseData.success();
        }else {
            return ResponseData.error("编辑失败");
        }
    }

    @PreAuthorize("hasAuthority('system:user:delete')")
    @ApiOperation("删除")
    @Log(title = "用户-删除",businessType = DELETE)
    @DeleteMapping("/{userIds}")
    public ResponseData delete(@PathVariable String[] userIds) {
        if(ArrayUtils.contains(userIds, 1)){
            return ResponseData.error("系统管理员不能删除");
        }
        if(ArrayUtils.contains(userIds, SecurityUtils.getUserId())){
            return ResponseData.error("当前用户不能删除");
        }

        boolean flag = userService.deleteByIds(userIds);
        if(flag){
            return ResponseData.success();
        }else {
            return ResponseData.error("删除失败");
        }
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @ApiOperation("状态修改")
    @Log(title = "用户-状态修改", businessType = UPDATE)
    @PatchMapping("/status/{userId}/{status}")
    public ResponseData changeStatus(@PathVariable("userId") String userId,@PathVariable("status") String status) {
        if(StringUtils.equals("1",userId)){
            return ResponseData.error("系统管理员不能编辑");
        }

        boolean flag = userService.changeStatus(userId,status);
        if (flag) {
            return ResponseData.success();
        } else {
            return ResponseData.error("操作失败");
        }
    }

    @PreAuthorize("hasAuthority('system:user:edit')")
    @ApiOperation("重置密码")
    @Log(title = "用户-重置密码", businessType = UPDATE)
    @PatchMapping("/password/{userId}/{password}")
    public ResponseData resetPwd(@PathVariable("userId") String userId,@PathVariable("password") String password) {
        if(StringUtils.equals("1",userId)){
            return ResponseData.error("系统管理员不能重置密码");
        }

        boolean flag = userService.resetPwd(userId,password);
        if (flag) {
            return ResponseData.success();
        } else {
            return ResponseData.error("操作失败");
        }
    }

    @PreAuthorize("hasAuthority('system:user:export')")
    @ApiOperation("导出数据")
    @Log(title = "用户-导出数据", businessType = EXPORT)
    @GetMapping("/export")
    public void export(User user, HttpServletResponse response) {
        try {
            //文件名称
            String fileName = DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
            //查询数据
            IPage<User> page = userService.findPage(new RequestData<User>(-1),user);

            List<User> list = page.getRecords();
            List<UserExportVO> voList = new ArrayList<>();

            list.forEach(l -> {
                UserExportVO vo = new UserExportVO();
                BeanUtils.copyProperties(l, vo);

                voList.add(vo);
            });

            new ExportExcel(null, UserExportVO.class).setDataList(voList).write(response, fileName).dispose();
        } catch (Exception e) {
            log.error("导出管理员列表成功失败",e);
            throw new RequestException("操作失败，请重试");
        }
    }

    @ApiOperation("导入数据")
    @Log(title = "用户-导入数据", businessType = IMPORT)
    @PreAuthorize("hasAuthority('system:user:import')")
    @PostMapping("/import")
    public ResponseData importData(MultipartFile file) throws Exception {

        if(ObjectUtils.isEmpty(file) || file.isEmpty()){
            return ResponseData.error();
        }

        ImportExcel excel = new ImportExcel(file, 0, 0);

        List<UserImportVO> list = excel.getDataList(UserImportVO.class);

        boolean flag = userService.saveImportData(list);

        if(flag){
            return ResponseData.success();
        }

        return ResponseData.error();
    }

    @PreAuthorize("hasAuthority('system:user:import')")
    @ApiOperation("下载导入模板")
    @GetMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        try {

            String fileName = "用户数据导入模板.xlsx";

            User user = userService.getById(SecurityUtils.getUserId());
            UserImportVO vo = new UserImportVO();
            BeanUtils.copyProperties(user,vo);

            List<UserImportVO> list = Lists.newArrayList(vo);

            new ExportExcel("", UserImportVO.class).setDataList(list).write(response, fileName).dispose();

        } catch (Exception e) {
            log.error("用户模板下载失败！失败信息：",e.getMessage());
            throw new BusinessException("用户模板下载失败，请重试！");
        }

    }





}
